package com.tanhua.dubbo.server.api;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.dubbo.config.annotation.Service;
import com.mongodb.client.result.DeleteResult;
import com.tanhua.dubbo.server.pojo.*;
import com.tanhua.dubbo.server.service.IdService;
import com.tanhua.dubbo.server.vo.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import javax.swing.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author YuShiLong
 * @Date 2021/4/15 22:23
 * @Version 1.0
 */
@Service(version = "1.0.0")
public class QuanziApiImpl implements QuanZiApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IdService idService;

    @Override
    public String savePublish(Publish publish) {

        //校验publish对象的id是否为空
        if (publish.getUserId() == null) {
            return null;
        }

        try {
            //填充数据
            publish.setId(ObjectId.get());
            publish.setCreated(System.currentTimeMillis());
            publish.setSeeType(1);//查看权限

            //增加一个自增长的pid
            publish.setPid(idService.createdId("publish", publish.getId().toHexString()));

            //保存数据到发布表中
            mongoTemplate.save(publish);

            //将数据写入自己的相册表中
            //定义一个Album，然后将数据赋值到album
            Album album = new Album();
            album.setId(ObjectId.get());
            album.setPublishId(publish.getId());//动态id
            album.setCreated(System.currentTimeMillis());

            //写入数据
            mongoTemplate.save(album, "quanzi_album_" + publish.getUserId());

            //将数据写入时间线表
            //查询当前用户好友的数据，将动态数据写入好友的时间线表中
            Query query = Query.query(Criteria.where("userId").is(publish.getUserId()));
            List<Users> users = mongoTemplate.find(query, Users.class);

            //遍历，写入数据
            for (Users user : users) {
                TimeLine timeLine = new TimeLine();
                timeLine.setId(ObjectId.get());
                timeLine.setPublishId(publish.getId());
                timeLine.setUserId(user.getUserId());
                timeLine.setDate(System.currentTimeMillis());

                mongoTemplate.save(timeLine, "quanzi_time_line_" + user.getFriendId());
            }
            return publish.getId().toHexString();
        } catch (Exception e) {
            //TODO 事务回滚
            e.printStackTrace();
        }

        return null;
    }

    @Override
    public PageInfo<Publish> queryPublishList(Long userId, Integer page, Integer pageSize) {

        //到MongoDB中查询自己的时间线表
        PageRequest pageRequest = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Order.desc("date")));//data为当前的时间戳
        Query query = new Query().with(pageRequest);//查询的时候没有条件(参数),只需要倒叙排序就行了

        String tableName = "quanzi_time_line_";
        if (null == userId) {
            //查询的是推荐动态
            tableName += "recommend";
        } else {
            //查询的是好友动态
            tableName += userId;
        }

        List<TimeLine> timeLines = mongoTemplate.find(query, TimeLine.class, tableName);

        //遍历时间线表,获取PublishId
        List<ObjectId> ids = new ArrayList<>();
        for (TimeLine timeLine : timeLines) {
            ids.add(timeLine.getPublishId());
        }

        //查询动态的信息
        Query queryPublish = Query.query(Criteria.where("id").in(ids)).with(Sort.by(Sort.Order.desc("created")));
        List<Publish> publishList = mongoTemplate.find(queryPublish, Publish.class);

        //封装分页对象
        PageInfo<Publish> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pageSize);
        pageInfo.setTotal(0);
        pageInfo.setRecords(publishList);

        return pageInfo;
    }

    @Override
    public boolean saveLikeComment(Long userId, String publishId) {

        //判断是否已经点赞,如果已经点赞就返回
        Criteria criteria = Criteria.where("userId").is(userId).and("publishId").is(new ObjectId(publishId)).and("commentType").is(1);
        Query query = Query.query(criteria);

        long count = mongoTemplate.count(query, Comment.class);

        if (count > 0) {
            //已经点赞
            return false;
        }
        return saveComment(userId, publishId, 1, null);
    }

    @Override
    public boolean removeComment(Long userId, String publishId, Integer commentType) {

        Criteria criteria = Criteria.where("userId").is(userId).and("publishId").is(new ObjectId(publishId)).and("commentType").is(commentType);
        Query query = Query.query(criteria);
        DeleteResult deleteResult = mongoTemplate.remove(query, Comment.class);
        return deleteResult.getDeletedCount() > 0;
    }

    @Override
    public boolean saveLoveComment(Long userId, String publishId) {

        //判断是否已经喜欢,如果已经喜欢就返回
        Criteria criteria = Criteria.where("userId").is(userId).and("publishId").is(new ObjectId(publishId)).and("commentType").is(3);
        Query query = Query.query(criteria);

        long count = mongoTemplate.count(query, Comment.class);

        if (count > 0) {
            //已经喜欢
            return false;
        }
        return saveComment(userId, publishId, 3, null);
    }

    @Override
    public boolean saveComment(Long userId, String publishId, Integer type, String content) {

        try {
            Comment comment = new Comment();
            comment.setId(ObjectId.get());
            comment.setUserId(userId);
            comment.setContent(content);
            comment.setPublishId(new ObjectId(publishId));
            comment.setCommentType(type);
            comment.setCreated(System.currentTimeMillis());

            Publish publish = mongoTemplate.findById(comment.getPublishId(), Publish.class);

            //设置发布人的id
            //判断有没有发布人id,没有的话就是直接点赞,有的话是是视频或者圈子点赞
            if (null != publish) {
                comment.setPublishUserId(publish.getUserId());
            } else {
                Video video = mongoTemplate.findById(comment.getPublishId(), Video.class);
                if (null != video) {
                    comment.setPublishUserId(video.getUserId());
                }
            }

            //将数据保存到MongoDB中
            mongoTemplate.save(comment);

            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

    @Override
    public Long queryCommentCount(String publishId, Integer type) {

        Criteria criteria = Criteria.where("publishId").is(new ObjectId(publishId)).and("commentType").is(type);
        Query query = Query.query(criteria);

        return mongoTemplate.count(query, Comment.class);
    }

    @Override
    public Publish queryPublishById(String id) {
        return this.mongoTemplate.findById(new ObjectId(id), Publish.class);
    }

    @Override
    public List<Publish> queryPublishByPids(List<Long> pids) {
        Query query = Query.query(Criteria.where("pid").in(pids));
        return this.mongoTemplate.find(query, Publish.class);
    }

    @Override
    public PageInfo<Comment> queryCommentList(String publishId, Integer page, Integer pageSize) {

        //倒叙排列
        PageRequest pageRequest = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Order.asc("created")));

        //构架查询条件，查询MongoDB获取评论列表
        Query query = Query.query(Criteria.where("publishId").is(new ObjectId(publishId))
                .and("commentType").is(2)).with(pageRequest);
        List<Comment> commentList = mongoTemplate.find(query, Comment.class);

        //填充数据
        PageInfo<Comment> pageInfo = new PageInfo<>();
        pageInfo.setTotal(0);
        pageInfo.setPageSize(pageSize);
        pageInfo.setPageNum(page);
        pageInfo.setRecords(commentList);

        return pageInfo;
    }

    //==============
    public PageInfo<Comment> queryCommentList(String publishId, Integer page, Integer pageSize, String sortProp, String sortOrder) {
        // 根据时间倒序设置分页
        PageRequest pageRequest = PageRequest.of(page - 1, pageSize,Sort.by(Sort.Order.desc("created")));
        Query query = Query.query(Criteria.where("publishId").is(new ObjectId(publishId))).with(pageRequest);
        List<Comment> comments = this.mongoTemplate.find(query, Comment.class);
        PageInfo<Comment> pageInfo = new PageInfo<>();
        pageInfo.setRecords(comments);
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pageSize);
        pageInfo.setTotal(comments.size());
        return pageInfo;
    }

    //=================

    @Override
    public PageInfo<Comment> queryCommentListByUser(Long userId, Integer type, Integer page, Integer pageSize) {

        PageRequest pageRequest = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Order.desc("created")));
        Query query = new Query(Criteria
                .where("publishUserId").is(userId)
                .and("commentType").is(type)).with(pageRequest);

        List<Comment> commentList = this.mongoTemplate.find(query, Comment.class);
        //填充数据
        PageInfo<Comment> pageInfo = new PageInfo<>();
        pageInfo.setTotal(0);
        pageInfo.setPageSize(pageSize);
        pageInfo.setPageNum(page);
        pageInfo.setRecords(commentList);

        return pageInfo;
    }

    @Override
    public PageInfo<Publish> queryAlbumList(Long userId, Integer page, Integer pageSize) {
        PageInfo<Publish> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pageSize);
        pageInfo.setTotal(0); //不提供总数

        PageRequest pageRequest = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Order.desc("created")));
        Query query = new Query().with(pageRequest);
        List<Album> albumList = this.mongoTemplate.find(query, Album.class, "quanzi_album_" + userId);

        if(CollectionUtils.isEmpty(albumList)){
            return pageInfo;
        }

        //查询相册所对应的动态信息
        List<ObjectId> publishIds = new ArrayList<>();
        for (Album album : albumList) {
            publishIds.add(album.getPublishId());
        }

        //查询发布信息
        Query queryPublish = Query.query(Criteria.where("id").in(publishIds)).with(Sort.by(Sort.Order.desc("created")));
        List<Publish> publishList = this.mongoTemplate.find(queryPublish, Publish.class);

        pageInfo.setRecords(publishList);

        return pageInfo;
    }


    //=======================================================================================

    /**
     *
     *      查询视频列表翻页
     *
     */
    public PageInfo<Video> queryVideoListById(Long userId, Integer page, Integer pageSize, String sortProp, String sortOrder) {
        PageRequest pageRequest=null;

        if (StringUtils.isNotEmpty(sortProp) && StringUtils.isNotEmpty(sortOrder)) {
            //设置排序

            Sort sortDesc = Sort.by(Sort.Order.desc(sortProp));
            Sort sortAsc = Sort.by(Sort.Order.asc(sortProp));

            if ("ascending".equals(sortOrder)) {
                pageRequest = PageRequest.of(page - 1, pageSize, sortAsc);
            } else {
                pageRequest = PageRequest.of(page - 1, pageSize, sortDesc);
            }

            Query query = Query.query(Criteria.where("userId").is(userId)).with(pageRequest);
            List<Video> videos = this.mongoTemplate.find(query, Video.class);
            PageInfo<Video> pageInfo = new PageInfo<>();
            pageInfo.setRecords(videos);
            pageInfo.setPageNum(page);
            pageInfo.setPageSize(pageSize);
            pageInfo.setTotal(videos.size());
            return pageInfo;
        }
        return null;
    }
}
